﻿using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Configuration;
using System.Web;
using System.Xml;

namespace MvcForum.Net.Bussiness
{

    public class WebConfigSectionHandler : IConfigurationSectionHandler
    {
        public object Create(object parent, object configContext, XmlNode section)
        {
            return new ForumConfiguration(section);
        }

    }


    public class ForumConfiguration
    {
        private const string CONFIG_SECTION = "MvcForum.Net";

        private static NameValueCollection values;


        public ForumConfiguration(XmlNode node)
        {
            values = new NameValueCollection();
            XmlNodeList nodes = node.ChildNodes;

            foreach (XmlNode _node in nodes)
            {

                values.Add(_node.Name, _node.InnerText);
            }
        }

        private static readonly Object _lock = new Object();

        public static ForumConfiguration Instant
        {
            get
            {
                lock (_lock)
                {

                    var settings = (ForumConfiguration)ConfigurationManager.GetSection(CONFIG_SECTION);

                    if (settings == null)
                    {
                        if (HttpContext.Current == null)
                            throw new ApplicationException("The main forum control is not design-time compatible due to it's complexity. Please load the individual page controls to modify the website.");
                        throw new ApplicationException("Failed to get configuration from Web.config.");
                    }
                    return settings;
                }

            }
        }

        public string this[string key]
        {
            get { return values[key]; }
        }

        public T GetValue<T>(string key)
        {
            if (values == null)
            {
                throw new ArgumentNullException("NameValueCollection is Null");
            }

            var value = values[key];
            var type = typeof(T);

            if (value == null)
            {
                if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
                    return default(T);

                throw new ArgumentOutOfRangeException("key");
            }

            var converter = TypeDescriptor.GetConverter(type);

            if (!converter.CanConvertTo(value.GetType()))
            {
                throw new ArgumentException(String.Format("Cannot convert '{0}' to {1}", value, type));
            }

            return (T)converter.ConvertTo(value, type);
        }


        public string Language
        {
            get { return this["Language"]; }
        }

        public double TimeZoneOffset
        {
            get { return GetValue<double>("TimeZone"); }
        }

        public string DateTimeFormat
        {
            get { return this["DateTimeFormat"] ?? "{0:F}"; }
        }

        public string DisallowedUserNames
        {
            get { return this["DisallowedUserNames"]; }
        }

        public string AllowEmails
        {
            get { return this["AllowEmails"]; }
        }

        public string AbsoluteUrl
        {
            get { return this["AbsoluteUrl"] ?? "/"; }
        }

        public string Extension
        {
            get { return this["Extension"]; }
        }

        public string HeadContent { get { return this["HeadContent"]; } }

        
        public string EncryptPassword
        {
            get { return this["EncryptPassword"]; }
        }


        public string ForumName
        {
            get { return this["ForumName"]; }
        }

        public string Keywords
        {
            get { return this["Keywords"]; }
        }

        public string Description
        {
            get { return this["Description"]; }
        }

        public string AdminEmail
        {
            get { return this["AdminEmail"]; }
        }


        public string SkinName
        {
            get { return this["SkinName"]; }
        }

      

        public int RequiredPostLength
        {
            get { return GetValue<int>("RequiredPostLength"); }
        }

        public int PastMinutes
        {
            get { return GetValue<int>("PastMinutes"); }

        }

      

        public int SecondsInCache
        {
            get { return GetValue<int>("SecondsInCache"); }
        }

        public int SearchResultInCache
        {
            get { return GetValue<int>("SearchResultInCache"); }
        }

        public int SearchFloodDelay
        {
            get { return GetValue<int>("SearchFloodDelay"); }
        }

        public int MaxSearchResults
        {
            get { return GetValue<int>("MaxSearchResults"); }
        }


        public bool AllowRegister
        {
            get { return Convert.ToBoolean(this["AllowRegister"]); }
        }

        public bool AllowGuestSearch
        {
            get { return Convert.ToBoolean(this["AllowGuestSearch"]); }
        }

        public int SearchResultType
        {
            get { return GetValue<int>("SearchResultType"); }
        }

        public bool AllowGuestReadForums
        {
            get { return bool.Parse(this["AllowGuestReadForums"]); }
        }

        public bool AllowGuestReadTopics
        {
            get { return bool.Parse(this["AllowGuestReadTopics"]); }
        }

        public bool AllowGuestDownload
        {
            get { return bool.Parse(this["AllowGuestDownload"]); }
        }

        public bool AllowUserLanguage
        {
            get { return bool.Parse(this["AllowUserLanguage"]); }
        }

        public bool AllowQuickReply
        {
            get { return Convert.ToBoolean(this["AllowQuickReply"]); }
        }


        public bool AllowClientActivityLogging
        {
            get
            {
                return Convert.ToBoolean(this["AllowClientActivityLogging"]);
            }
        }


        public bool AutoFeedbackErrorException
        {
            get
            {
                return Convert.ToBoolean(this["AutoFeedbackErrorException"]);
            }
        }



        public bool RegisterEmailActiveRequired
        {
            get { return bool.Parse(this["RegisterEmailActiveRequired"]); }
        }

        public int NewReplyDaysAgo
        {
            get { return GetValue<int>("NewReplyDaysAgo"); }
        }

        public int HotReplyThreshold
        {
            get { return GetValue<int>("HotReplyThreshold"); }
        }


        public int TopicShowWordsLength
        {
            get { return GetValue<int>("TopicShowWordsLength"); }
        }

        public int ButtonPageRenderPosition
        {
            get { return GetValue<int>("ButtonPageRenderPosition"); }
        }





        public bool AllowGuestReport
        {
            get { return Convert.ToBoolean(this["AllowGuestReport"]); }
        }

        public bool WhenReportSendAdminEmail
        {
            get { return Convert.ToBoolean(this["WhenReportSendAdminEmail"]); }
        }

        public bool WhenNewPostSendAdminEmail
        {
            get { return Convert.ToBoolean(this["WhenNewPostSendAdminEmail"]); }
        }


        public string SmilePath
        {
            get { return this["SmilePath"]; }
        }


        public string UploadPath
        {
            get { return this["UploadPath"]; }
        }


        public int PageSize
        {
            get { return Convert.ToInt32(this["PageSize"]); }
        }

        public int SiteMapPageSize
        {
            get { return Convert.ToInt32(this["SiteMapPageSize"]); }
        }


        public bool AllowRssFeed
        {
            get { return Convert.ToBoolean(this["AllowRssFeed"]); }
        }

        public int FeedPageSize
        {
            get { return Convert.ToInt32(this["FeedPageSize"]); }
        }


        public string WhoisIpAddress
        {
            get { return this["WhoisIpAddress"]; }
        }


        #region Avatar

        public string AvatarPath
        {
            get { return this["AvatarPath"]; }
        }


        public int AvatarWidth
        {
            get { return GetValue<int>("AvatarWidth"); }
        }

        public int AvatarHeight
        {
            get { return GetValue<int>("AvatarHeight"); }
        }
        #endregion


        public bool NoFollowExternalLinks
        {
            get { return Convert.ToBoolean(this["NoFollowExternalLinks"]); }
        }


        public string AllowFollowDomains
        {
            get { return this["AllowFollowDomains"]; }
        }

        public bool AllowShareToSocial
        {
            get
            {
                return Convert.ToBoolean(this["AllowShareToSocial"]);
                
            }
        }

        public string SocialSharingWidget
        {
            get { return this["SocialSharingWidget"]; }
        }



        #region AttachFile

        public bool AllowAttachFile
        {
            get { return bool.Parse(this["AllowAttachFile"]); }
        }


        public string FileManagerScript
        {
            get { return this["FileManagerScript"]; }
        }
        public string ThumbnailScript
        {
            get { return this["ThumbnailScript"]; }
        }

        public string IconFileTypePath
        {
            get
            {
                return this["IconFileTypePath"];
            }
        }

        public string ThumbnaiCachePath
        {
            get { return this["ThumbnaiCachePath"]; }
        }

        #endregion



        #region Smtp

        public string SmtpServer
        {
            get { return this["SmtpServer"]; }
        }

        public int SmtpPort
        {
            get { return Convert.ToInt32(this["SmtpPort"]); }
        }

        public string SmtpSender
        {
            get { return this["SmtpSender"]; }
        }

        public bool SmtpCredentials
        {
            get { return Convert.ToBoolean(this["SmtpCredentials"]); }
        }

        public string SmtpUserName
        {
            get { return this["SmtpUserName"]; }
        }

        public string SmtpUserPass
        {
            get { return this["SmtpUserPass"]; }
        }

        public bool SmtpSsl
        {
            get { return Convert.ToBoolean(this["SmtpSsl"]); }
        }

        #endregion
    }

}
